home *** CD-ROM | disk | FTP | other *** search
- Documentation of C-Client Functions and Interfaces
-
- Mark Crispin
- Revised 15 December 1991
-
- Introduction
-
- The C-Client was originally written at Stanford University as a
- set of routines to support IMAP and SMTP from a main program which
- would handle the user interface. A sample main program which uses the
- C-Client, MTEST.C, has run on a wide variety of platforms including
- Unix, TOPS-20, Macintosh, and MS-DOS.
-
- This is a major redesign of the original C-Client, made at the
- University of Washington. It uses ANSI C calling conventions
- throughout to assist in function argument type checking. It also
- provides the capability of having multiple means of accessing mail
- through the user of "drivers". A future version of the C-Client will
- probably convert the current direct usage of SMTP to a driver as well.
-
- The most important file for the author of an application using
- the C-Client is MAIL.H. MAIL.H defines several important structures
- of data which are passed between the main program and the C-Client.
- Although some functions (e.g. mail_fetchtext()) return the data
- fetched as a convenience, for some data items (e.g. flags) you need to
- get the data as a structure reference. MAIL.H also defines a number
- of useful constants.
-
- It should be noted that when MAIL functions exist to reference
- data they should be used in preference to referencing the structures
- directly. This is because in some cases the data is not actually
- fetched until a reference (via the function call) is made. For
- example, although the MESSAGECACHE item for a message can be obtained
- by indexing messagarray, there is no guarantee that the item in fact
- exists unless mail_fetchenvelope() is called for that message. Less
- costly functions, mail_fetchfast() and mail_fetchflags(), also exist
- to create and load a MESSAGECACHE item, but their usage is not
- recommended.
-
- The main program will probably also need to include SMTP.H,
- MISC.H, and OSDEP.H, but this usage should be solely to receive
- function prototypes. Any other definitions in those files should be
- considered private to that module.
-
- I. Public interface
-
- The files listed in this section are the standard C-Client
- mailsystem library modules, and are operating system and machine
- independent. Only those functions suitable for external callers are
- documented here; other functions are for internal use only and are
- used by external callers at their own risk!
-
- [MAIL.C]: Mail Access functions
-
- [Note!! There is an important difference between a "sequence" and a
- "msgno". A sequence is a string representing one or more messages in
- IMAP2-style sequence format ("n", "n:m", or combination of these delimited
- by commas), whereas a msgno is an int representing a single message.]
-
- void mail_link (DRIVER *driver)
- This function adds the specified driver to the list of mail drivers.
- Initially there are no drivers, so all programs which intend to use
- the MAIL routines need to have at least one call to this function. A
- function which uses IMAP2 would have a statement such as:
- mail_link (&imapdriver); /* link in IMAP driver */
- early in the program's initialization.
-
- void mail_find (MAILSTREAM *stream,char *pat);
- This function finds known mailboxes that match the given wildcard
- pattern. The application's mm_mailbox() function is called for each
- matching mailbox.
-
- void mail_find_bboards (MAILSTREAM *stream,char *pat);
- This function finds known bboards that match the given wildcard
- pattern. The application's mm_bboard() function is called for each
- matching mailbox.
-
- MAILSTREAM *mail_open (MAILSTREAM *oldstream,char *name,int debug)
- This function opens the mailbox and if successful returns a stream
- suitable for use by the other MAIL functions. If oldstream is
- non-NIL, an attempt is made to reuse oldstream as the stream for this
- mailbox. If debug is non-NIL, the stream is set for debugging. NIL
- is returned if this function fails for any reason.
-
- MAILSTREAM *mail_close (MAILSTREAM *stream)
- This function closes the MAIL stream and frees all resources
- associated with it that it may have created (subject to any handles
- existing).
-
- MAILHANDLE *mail_makehandle (MAILSTREAM *stream)
- This function creates and returns a handle to the stream, suitable
- for use as a secondary copy of the stream. This is useful when some
- entity that wishes to access the stream may survive the stream without
- knowing that it outlived it. For example, an object reading a message
- may have a handle to a stream, but the message selection object that
- spawned it (and which owns the stream) may have gone away. A stream
- can be closed or recycled while handles are pointing at it, but it is
- not completely freed until all handles are gone. A stream may have an
- arbitrary number of handles.
-
- void mail_free_handle (MAILHANDLE **handle)
- This function frees the handle and notifies the stream that it has
- one fewer handle. If this is the last handle on the stream and the
- stream has been closed, then the stream is freed.
-
- MAILSTREAM *mail_stream (MAILHANDLE *handle)
- This function returns the stream associated with the handle if and
- only if the stream still represents the same MAIL connection associated
- with the handle. Otherwise, NIL is returned (meaning that there is no
- active stream associated with this handle).
-
- void mail_fetchfast (MAILSTREAM *stream,char *sequence)
- This function causes a fetch of all the "fast" information (internal
- date, RFC 822 size, and flags) for the given sequence. Since all this
- information is also fetched by mail_fetchenvelope(), this function is
- generally not used.
-
- void mail_fetchflags (MAILSTREAM *stream,char *sequence)
- This function causes a fetch of the flags for the given sequence.
- This main reason for using this function is to update the flags in the
- local cache in case some other process changed the flags (multiple
- simultaneous write access is allowed to the flags) as part of a "check
- entire mailbox" (as opposed to "check for new messages") operation.
-
- ENVELOPE *mail_fetchenvelope (MAILSTREAM *stream,int msgno)
- This function causes a fetch of all the information (envelope,
- internal date, RFC 822 size, flags, and body structure) for the given
- msgno and in the case of IMAP up to MAPLOOKAHEAD (a parameter in
- IMAP2.H) subsequent messages which are not yet in the cache. No fetch
- is done if the envelope for the given msgno is already in the cache.
- The ENVELOPE for this msgno is returned.
- This is the primary function for fetching non-text information about
- messages, and should be called before any attempt to reference cache
- information about this message via mail_elt().
- After this function has been called the message body structure
- information can be obtained by using: mail_elt (stream,msgno)->body
-
- char *mail_fetchheader (MAILSTREAM *stream,int msgno)
- This function causes a fetch of the complete, unfiltered RFC 822
- format header of the specified message as a text string and returns
- that text string.
-
- char *mail_fetchtext (MAILSTREAM *stream,int msgno)
- This function causes a fetch of the non-header text of the specified
- message as a text string and returns that text string. No attempt is
- made to segregate individual body parts.
-
- char *mail_fetchbody (MAILSTREAM *stream,int m,char *sec,unsigned long *len)
- This function causes a fetch of the particular section of the body of
- the specified message as a text string and returns that text string.
- The section specification is a string of integers delimited by period
- which index into a body part list as per the IMAP body parts extension
- RFC. The length of the body part, which may not necessarily be
- null-terminated, is returned in len. Body parts are not decoded by
- this function; see rfc822_base64() and rfc822_quotedprintable().
-
- char *mail_fetchfrom (MAILSTREAM *stream,int msgno,int length)
- This function returns a "from" string of the specified length for the
- specified message, suitable for display to the user in a menu line.
- If the personal name of the first address in the envelope's from item
- is non-NIL, it is used; otherwise a string is created by appending the
- mailbox of the first address, an "@", and the host of the first
- address. The string is trimmed or padded with trailing spaces as
- necessary to make its length match what the caller requested.
- The length argument is provided to make it convenient for the
- application to decide upon the length it wants. It should be
- considered a constant, since once generated the string is kept in the
- cache and is returned on subsequent calls instead of recomputed.
-
- char *mail_fetchsubject (MAILSTREAM *stream,int msgno,int length)
- This function returns a "subject" string of the specified length for
- the specified message, suitable for display to the user in a menu
- line.
- The envelope's subject item is copied and trimmed as necessary to
- make its length be no more what the caller requested. Unlike
- mail_fetchfromstring(), this function can return a string of shorter
- length than what the caller requested.
- The warning about the length argument in mail_fetchfromstring() also
- applies to this function.
-
- MESSAGECACHE *mail_elt (MAILSTREAM *stream,int msgno)
- This function returns the cache entry for the specified message, and
- is preferred over using stream->messagearray[msgno-1].
- Although this function will create a cache entry if it does not
- already exist, that functionality is for internal use only. This
- function should never be called without having first called
- mail_fetchenvelope() on the message first.
-
- void mail_setflag (MAILSTREAM *stream,char *sequence,char *flag)
- This function causes a store to add the specified flag to the flags
- set for the messages in the specified sequence. If there is any
- problem in setting flags, a message will be passed to the application
- via the mm_log() facility.
-
- void mail_clearflag (MAILSTREAM *stream,char *sequence,char *flag)
- This function causes a store to delete the specified flag from the
- flags set for the messages in the specified sequence. If there is any
- problem in clearing flags, a message will be passed to the application
- via the mm_log() facility.
-
- void mail_search (MAILSTREAM *stream,char *criteria)
- This function causes a mailbox search using the specified criteria
- (in IMAP2 format). The application's mm_searched() function is called
- for each message that matches the search criteria. If there is any
- problem in searching, a message will be passed to the application via
- the mm_log() facility.
-
- int mail_ping (MAILSTREAM *stream)
- The function pings the stream to see if it is still active. It may
- cause an "implicit check" for new mail. It returns T if the stream is
- still alive, NIL otherwise.
-
- void mail_check (MAILSTREAM *stream)
- This function causes an explicit check of the mailbox for new
- messages including a remote reparse of all flags in the mailbox. The
- application's mm_exists() function is called with the number of
- messages in the mailbox. The status of the check is passed to the
- application via the mm_log() facility.
- Note that mail_fetchflags() needs to be called to update the flags in
- the local cache.
-
- void mail_expunge (MAILSTREAM *stream)
- This function causes an expunge of the mailbox. The application's
- mm_expunged() function is called for each message that has been
- expunged. The application's mm_exists() function is called at the
- start and end of the expunge to ensure synchronization. The status of
- the expunge is passed to the application via the mm_log() facility.
- Note that the decrementing of msgno's for subsequent messages happens
- immediately; for example, if three consequtive messages starting at
- msgno 5 are expunged, mm_expunged() will be called with a msgno of 5
- three times.
-
- int mail_copy (MAILSTREAM *stream,char *sequence,char *mailbox)
- This function causes the messages in the specified sequence to be
- copied to the specified mailbox. The system \Seen flag is set for
- these messages and T is returned if the copy is successful.
- If there is any problem in copying, a message will be passed to the
- application via the mm_log() facility and the function returns NIL.
- Note that the mailbox must be on the same host as the stream and is a
- mailbox only.
-
- int mail_move (MAILSTREAM *stream,char *sequence,char *mailbox)
- This function causes the messages in the specified sequence to be
- copied to the specified mailbox. The system \Seen and \Deleted flags
- are set for these messages and T is returned if the copy is successful.
- If there is any problem in copying, a message will be passed to the
- application via the mm_log() facility and the function returns NIL.
- Note that the mailbox must be on the same host as the stream and is a
- mailbox only.
-
- void mail_debug (MAILSTREAM *stream)
- This function enables telemetry logging for this stream. All
- telemetry is passed to the application via the mm_dlog() facility.
-
- void mail_nodebug (MAILSTREAM *stream)
- This function disables telemetry logging for this stream.
-
- ENVELOPE *mail_newenvelope ()
- This function returns a new, empty envelope.
-
- ADDRESS *mail_newaddr ()
- This function returns a new, empty address.
-
- BODY *mail_newbody ()
- This function returns a new, empty body.
-
- PART *mail_newbody_part ()
- This function returns a new, empty body part.
-
- void mail_free_body (BODY **body)
- This function frees a body and all its contents.
-
- void mail_free_body_part (PART **part)
- This function frees a body part and all its contents.
-
- void mail_free_elt (MESSAGECACHE **elt)
- This function frees a cache element. Normally, this is used only if
- the main program has a private pointer to cache elements. If so, it
- is expected to increment the cache element's lockcount when it makes a
- private pointer, and to call this function when it is finished with it.
-
- void mail_free_envelope (ENVELOPE **env)
- This function frees an envelope and all its contents.
-
- void mail_free_address (ADDRESS **address)
- This function frees an address and all its contents.
-
- [MISC.C]: Miscellaneous utility functions
-
- char *ucase (char *string)
- This function converts each lowercase character of the specified
- string to uppercase and returns the string.
-
- char *lcase (char *string)
- This function converts each uppercase character of the specified
- string to lowercase and returns the string.
-
- char *cpystr (char *string);
- This function returns a copy of the string.
-
- int find_rightmost_bit (long *valptr)
- This function returns -1 if the 32-bit value pointed to by valptr is
- non-zero, otherwise it returns the bit number (0 = LSB, 31 = MSB) of
- the right-most bit in that value. This is used to convert from the
- bits in the cache's userFlags item to an index into the stream's
- userFlags array of flag texts.
-
- long min (long i,long j)
- This function returns the minimum of the two integers.
-
- long max (long i,long j)
- This function returns the maximum of the two integers.
-
- int search (char *s,int c,char *pat,int patc)
- This function does a fast case-independent search for the given
- pattern in pat (lenth patc) in base string s, and returns T if the
- pattern is found in the string.
-
- [SMTP.C]: Mail Transfer Protocol functions
-
- SMTPSTREAM *mtp_open (char **hostlist,int debug)
- This function opens an MTP connection to a one of the hosts in the
- host list and if successful returns a stream suitable for use by the
- other MTP functions. The hosts are tried in order until a connection
- is successfully opened. If debug is non-NIL, mtp_debug() is called on
- the stream immediately after the TCP connection is opened so that the
- greeting and hello protocol goes into the debugging telemetry. NIL is
- returned if this function fails to open a connection to any of the
- hosts in the list.
-
- void mtp_close (SMTPSTREAM *stream)
- This function closes the MTP stream and frees all resources
- associated with it that it may have created.
-
- int mtp_mail (SMTPSTREAM *stream,char *type,ENVELOPE *msg,BODY *body)
- This function negotiates an MTP transaction of the specified type
- (one of "MAIL", "SEND", "SAML", or "SOML") to deliver the specified
- message. This function returns T if success or NIL if there is any
- failure. The text reason for the failure is in the stream's reply
- item; if it is associated with a recipient it is also in that address'
- error item.
-
- MTPADR *mtp_parse_address (char *string,char *defaulthost)
- This function parses a string that contains an address list and
- returns an address list suitable for the to, cc, or bcc items of a
- message. The address list should be freed via mtp_free_address() when
- the application is finished with it. If there are any parsing errors
- a message is passed to the application via the mm_log() facility.
-
- void mtp_debug (SMTPSTREAM *stream)
- This function enables SMTP protocol telemetry logging for this
- stream. All SMTP protocol operations are passed to the application
- via the mm_dlog() facility.
-
- void mtp_nodebug (SMTPSTREAM *stream)
- This function disables SMTP protocol telemetry logging for this
- stream.
-
- [RFC822.C]: RFC 822 Protocol support functions
-
- [Note: direct usage of the functions in this module is strongly discoraged,
- since it creates a dependency upon RFC 822.]
-
- void rfc822_header (char *header,ENVELOPE *env,BODY *body)
- This function writes an RFC 822 format header into header based on
- the information in message.
-
- void rfc822_write_address (char *destination,ADDRESS *address)
- This function writes an RFC 822 format address list into destination
- based on the information in address and is therefore the inverse of
- mtp_parse_address().
-
- void rfc822_parse_msg (ENVELOPE **en,BODY **bdy,char *s,unsigned long i,
- char *b,unsigned long j,char *host,char *tmp)
- This function parses the RFC 822 header pointed to by s with count i
- and body pointed to by b with count j into the specified destination
- envelope and body pointers, using host as the default host name and
- tmp as a scratch buffer. This function is intended solely to support
- header parsing for non-IMAP MAIL drivers.
-
- void rfc822_parse_adrlist (ADDRESS **lst,char *string,char *host)
- This function is similar to mtp_parse_address(), except that the
- destination list is one of the arguments. If the destination list is
- non-empty it appends the new addresses to the list.
-
- void *rfc822_base64 (char *src,unsigned long srcl,unsigned long *len)
- This function decodes a BASE64 body part given a source string and
- its length. The decoded body part as a sequence of binary bytes is
- returned, and its length is returned in len.
-
- char *rfc822_quotedprintable (char *src,unsigned long srcl,unsigned long *len)
- This function decodes a Quoted-Printable body part given a source
- string and its length. The decoded body part as an 8-bit character
- string is returned, and its length is returned in len.
-
- II. Main program co-routines
-
- All main programs which use the C-Client must have the following
- service co-routines:
-
- [Main program]
-
- #include "mail.h"
- #include "smtp.h"
- #include "misc.h"
- #include "osdep.h"
-
- void mm_searched (MAILSTREAM *stream,int number)
- This function is called from mail_search to notify the main program
- that this message number matches the search. Note that the stream is
- locked and that therefore you cannot call any mail_xxx functions!
-
- void mm_exists (MAILSTREAM *stream,int number)
- This function is called from several functions to notify the main
- program that there are this many messages in the mailbox. It is also
- used to notify the main program of new mail, by announcing a higher
- number than the main program was previously aware. Note that the
- stream is locked and that therefore you cannot call any mail_xxx
- functions!
-
- void mm_expunged (MAILSTREAM *stream,int number)
- This function is called from mail_expunge to notify the main program
- that this message number has been expunged from the mail file and that
- all subsequent messages are now referenced by a message number one
- less than before. This implicitly decrements the number of messages
- in the mailbox. Note that the stream is locked and that therefore you
- cannot call any mail_xxx functions!
-
- void mm_mailbox (char *string)
- This function is called from mail_find to notify the main program
- that this mailbox matches the find request. Note that the stream is
- locked and that therefore you cannot call any mail_xxx functions!
-
- void mm_bboard (char *string)
- This function is called from mail_find_bboards to notify the main
- program that this bboard matches the find request. Note that the
- stream is locked and that therefore you cannot call any mail_xxx
- functions!
-
- void mm_notify (MAILSTREAM *stream,char *string,int errflg)
- This function is called when an unsolicited response of type OK, NO,
- or BAD from a remote IMAP server is received. No newline is included
- in the string, so this function has to output its own. The IMAP
- protocol defines this facility as a means for the server to transmit
- text for the end user to see. Although the behavior of all possible
- IMAP server implementations can not be predicted, the following
- general assumptions can be made about the value of errflg and how it
- relates to the text based on how the c-client based IMAP server
- behaves:
- NIL normal operation. The text is `babble' that the server
- thinks may be interesting to the user. Examples: the
- greeting message from the server, notice of enabling of the
- kludge to support MacMS, error in parsing the header of a
- message in the remote mailbox (a c-client PARSE mm_log()
- event). Display of these messages to the user is optional.
- WARN A c-client WARN mm_log() event which occurred in the server.
- See mm_log() documentation below. This is also called from
- the Berkeley mail driver if the requested mailbox write
- operation failed because the main program returned NIL from
- a "non-serious" mm_diskerror() call.
- ERROR An unknown IMAP protocol error, or an extremely serious
- internal error. These are supposedly impossible in debugged
- software, and so should be called to the attention of the user
- and/or support staff. Whatever happened has probably already
- disrupted the user's work, so it is alright to deal with this
- in a modal fashion.
- Note that usually the stream is locked and that therefore you cannot
- call any mail_xxx functions!
-
- void mm_log (char *string,int errflg)
- This function is called on various c-client events. No newline is
- included in the string, so this function has to output its own. In
- general, it is intended that these be messages for the user to see.
- The value of errflg indicates the urgency of these messages, as
- follows:
- NIL normal operation. The text is `babble' that the c-client
- thinks may be interesting to the user. Typically, these are
- acknowledgement texts from various operations ("Expunged 3
- messages", "Re-using connection", "Connection closing") which
- may contain useful information. Display of these messages to
- the user is optional depending upon the needs of the
- application.
- PARSE an error occurred in RFC 822 parsing. Since bogus headers are
- an all-too-common occurrence in the real word, these can often
- be ignored on the GIGO principle. However, it may be a good
- idea to report these errors if calling the rfc822 routines as
- part of command parsing e.g. mtp_parse_address().
- WARN an error condition occurred that did not abort the requested
- operation, or which has a well-defined "right thing to do"
- when it happens. This can be things such as "Can't open
- mailbox for read-write, so opening read-only", "Empty
- mailbox", "Login failed, try again", "Waiting for mailbox to
- become unlocked", etc. Warnings can also occur if the abort
- option is taken from mm_diskerror() to verify that the abort
- has taken place. Furthermore, it can occur (in massive
- quantities!) in the event of a c-client detected IMAP
- protocol error; but this should never happen in debugged
- software. Warnings should be called to the user's attention,
- but probably should not interrupt the flow of the user's work
- (that is, it's alright to display warnings in a view area
- without waiting for any user acknowledgement of seeing the
- warning). It is not, however, absolutely necessary for an
- application to display warnings.
- ERROR a serious error condition occured that aborted the requested
- operation and possibly also aborted the mail stream. This
- ranges from normal error conditions such as "Can't open
- mailbox", "too many login failures, go away" to bizarre
- conditions such as "Apparent new mail appeared in the mailbox
- that doesn't look like mail, program aborting". Errors must
- be called to the user's attention, and probably should require
- some sort of acknowledgement (e.g. answering a modal panel)
- before the application proceeds.
- Note that usually the stream is locked and that therefore you cannot
- call any mail_xxx functions!
-
- void mm_dlog (char *string)
- This function is called from several functions to output a string to
- a debugging telemetry stream. No newline is included in the string,
- so this function has to output its own. This is called only when
- debugging is enabled on the stream in question. Note that usually the
- stream is locked and that therefore you cannot call any mail_xxx
- functions!
-
- void mm_login (char *host,char *user,char *pwd,int trial)
- This function is called to get a user name and password for the given
- host. The function stores the user name and password in the strings
- pointed to by the appropriate arguments. The trial argument is the
- number of attempts to perform the login and is initially zero (e.g.
- for a default username and password login functionality). It is
- incremented for each subsequent trial until the maximum number of
- trials are made. Note that the stream is locked and that therefore
- you cannot call any mail_xxx functions!
-
- void mm_critical (MAILSTREAM *stream)
- This function is called to alert the application that the c-client is
- about to run some critical code that may result in a clobbered mail
- file if it is interrupted. Note that the stream is locked and that
- therefore you cannot call any mail_xxx functions!
-
- void mm_nocritical (MAILSTREAM *stream)
- This function is called to alert the application that the c-client is
- no longer running critical code that may result in a clobbered mail
- file if it is interrupted. Note that the stream is locked and that
- therefore you cannot call any mail_xxx functions!
-
- int mm_diskerror (MAILSTREAM *stream,int errcode,int serious)
- This function is called to alert the application that the c-client
- has encountered an unrecoverable write error when trying to update the
- mail file. errcode contains the system error code. If serious is
- non-zero, then it is probable that the disk copy of the mailbox has
- been damaged. The return value from this function is the abort flag;
- if serious is zero and the abort flag is non-zero, the operation is
- aborted. If the abort flag is zero or if serious was non-zero, a
- return from this function will retry the failing operation.
-
- void mm_fatal (char *string)
- This function is called from the fatal() routine in the operating
- system code to notify the main program that it is about to crash. The
- string contains a reason. At the very minimum, the main program
- should do something like
- mm_log (string,ERROR);
- and then return. No newline is included in the string, so this
- function has to output its own.
-
- * * * IMPORTANT * * *
-
- Any multi-tasking application should test stream->lock prior to
- calling any functions in this module. Any attempt to do a mail_*
- operation while one is already in progress on the same stream will
- cause the application to fail in unpredictable ways, mostly likely due
- to the _exit() calls in the internal mail_lock() routine when it
- discovers the stream is already locked.
-
- Note that this check is insufficient in a preemptive-scheduling
- multi-tasking application due to the possibility of a timing race.
- Such applications must be written so that only one process accesses
- the stream, or to have a higher level lock.
-
- Since MAIL operations will not finish until they are completed, a
- single-tasking application does not have to worry about this problem,
- except in the co-routines invoked from MAIL (e.g. mm_exists(), etc.)
- in which case the stream is *always* locked.
-
-
- III. Operating system-dependent public interface
-
- The files listed below must be rewritten for each port of the
- C-Client to a new operating system.
-
- [OSDEP.C]: operating system-dependent functions
-
- #include "mail.h"
- #include "osdep.h"
-
- void rfc822_date (char *date)
- This function is called to get the current date and time in an RFC 822
- format string into the the string pointed to by the argument.
-
- void *fs_get (int size)
- This function allocates and returns a block of free storage of the specified
- size. Unlike malloc(), there is no failure return.
-
- void fs_resize (void **block,int size)
- This function resizes the free storage block, updating the pointer if
- necessary. Unlike realloc(), there is no failure return.
-
- void fs_give (void **block)
- This function releases a block of free storage allocated by fs_get and
- zeros the block pointer.
-
- void fatal (char *string)
- This function is called when an "impossible" error is detected and the
- client wishes to crash. The string argument contains a reason string.
-
- char *strcrlfcpy (char **dst,long *dstl,char *src,long srcl)
- This function is called to copy into a destination string dst of size dstl
- (resized if necessary), a CRLF newline form string from local string src of
- size srcl.
-
- TCPSTREAM *tcp_open (char *host,int port)
- This function is called to open a TCP connection to the given host
- name on the given port number. It returns a TCPSTREAM, which is an
- internal data structure for this file and is implementation-dependent.
- NIL is returned if this function fails for any reason.
-
- char *tcp_getline (TCPSTREAM *stream)
- This function returns a malloc() string containing a null-terminated
- text line from the TCP stream. The CR/LF which terminated the line is
- not included. The caller should free() the string when it is finished
- with it. NIL is returned if this function fails for any reason.
-
- tcp_getbuffer (TCPSTREAM *stream,int size,char *buffer)
- This function reads the requested number of bytes into the indicated
- buffer. This function returns T if successful and NIL if it fails for
- any reason.
-
- int tcp_soutr (TCPSTREAM *stream,char *string)
- This function writes the indicated (null-terminated) string to the
- TCP stream. This function returns T if successful and NIL if it fails
- for any reason.
-
- int tcp_close (TCPSTREAM *stream)
- The function closes the TCP stream and frees all resources associated
- with it that it may have created.
-
- char *tcp_host (TCPSTREAM *stream)
- This function returns the stream's foreign host name string.
-
- char *tcp_localhost (TCPSTREAM *stream)
- This function returns the stream's local host name string.
-
- IV. Driver interface
-
- When writing a new driver for the C-Client, you must provide a
- DRIVER stucture giving a dispatch vector between MAIL and the driver.
- The DRIVER dispatch vector is described in MAIL.H.
-
- [driver.C]: driver for a particular mailbox type
-
- #include "mail.h"
- #include "driver.h"
- #include "misc.h"
- #include "osdep.h"
-
- DRIVER *next;
- The first entry is a DRIVER * pointer to the next driver which this
- application supports (or NIL if this is the last driver). Drivers are
- lunk together via the mail_link() function. The remaining entries are
- function pointers as follows
-
- DRIVER *driver_valid (char *name)
- This function returns a pointer to the driver's DRIVER dispatch
- vector iff this driver accepts the given name as a valid mailbox for
- this driver. Otherwise, it returns the value of the next driver's
- driver_valid() or NIL if there is no next driver. In other words,
- calling driver_valid() for the first driver will return the driver
- dispatch vector for the driver which supports this type of mailbox.
-
- void driver_find (MAILSTREAM *stream,char *pat)
- This function implements mail_find() function for this driver.
-
- void driver_find_bboard (MAILSTREAM *stream,char *pat);
- This function implements mail_find_bboard() function for this driver.
-
- MAILSTREAM *driver_open (MAILSTREAM *stream)
- This function opens the mailbox identified by the given stream. It
- may use the data on the stream and create additional data on
- stream->local as necessary. It should return the given stream unless
- it failed to open the mailbox, in which case it should return NIL.
-
- void driver_close (MAILSTREAM *stream)
- This function implements mail_close() function for this driver.
-
- void driver_fetchfast (MAILSTREAM *stream,char *sequence)
- This function implements mail_fetchfast() function for this driver.
-
- void driver_fetchflags (MAILSTREAM *stream,char *sequence)
- This function implements mail_fetchflags() function for this driver.
-
- ENVELOPE *driver_fetchenvelope (MAILSTREAM *stream,int msgno)
- This function implements mail_fetchenvelope() function for this
- driver.
-
- char *driver_fetchheader (MAILSTREAM *stream,int msgno)
- This function implements mail_fetchheader() function for this driver.
-
- char *driver_fetchtext (MAILSTREAM *stream,int msgno)
- This function implements mail_fetchtext() function for this driver.
-
- char *driver_fetchbody (MAILSTREAM *stream,int msgno,char *section)
- This function implements mail_fetchbody() function for this driver.
-
- void driver_setflag (MAILSTREAM *stream,char *sequence,char *flag)
- This function implements mail_setflag() function for this driver.
-
- void driver_clearflag (MAILSTREAM *stream,char *sequence,char *flag)
- This function implements mail_clearflag() function for this driver.
-
- void driver_search (MAILSTREAM *stream,char *criteria)
- This function implements mail_search() function for this driver.
-
- int driver_ping (MAILSTREAM *stream)
- This function implements mail_ping() function for this driver.
-
- void driver_check (MAILSTREAM *stream)
- This function implements mail_check() function for this driver.
-
- void driver_expunge (MAILSTREAM *stream)
- This function implements mail_expunge() function for this driver.
-
- int driver_copy (MAILSTREAM *stream,char *sequence,char *mailbox)
- This function implements mail_copy() function for this driver.
-
- int driver_move (MAILSTREAM *stream,char *sequence,char *mailbox)
- This function implements mail_move() function for this driver.
-
- Drivers may call all of the MAIL functions documented above plus
- the following co-routine support functions:
-
- void mail_searched (MAILSTREAM *stream,int msgno)
- This function is called by the driver to notify MAIL that this
- message number matches a search. It invokes the main program's
- mm_searched() function.
-
- void mail_exists (MAILSTREAM *stream,int nmsgs)
- This function is called by the driver to notify MAIL that this
- message number exists (i.e. there are this many messages in the
- mailbox). It invokes the main program's mm_exists() function.
-
- void mail_recent (MAILSTREAM *stream,int recent)
- This function is called by the driver to notify MAIL that this
- many messages are "recent" (i.e. arrived in the mailbox since the
- previous time the mailbox was opened).
-
- void mail_expunged (MAILSTREAM *stream,int msgno)
- This function is called by the driver to notify MAIL that this
- message number has been expunged from the mail file and that all
- subsequent messages are no references by a message number one less
- than before. It invokes the main program's mm_expunged() function.
-
- void mail_lock (MAILSTREAM *stream)
- This function sets the stream lock. It is an error to set the stream
- lock if the stream is already locked.
- This is mainly used to catch errors due to a co-routine function
- (e.g. mm_exists) inadvertantly recursing back to the MAIL routines and
- establishing an infinite recursion. Normally, drivers will set the
- lock prior to calling one of the co-routine functions above or, more
- likely, in the beginning of the driver's non-reentrant "do operation"
- section. In the IMAP2 driver, the stream lock is set when entering
- imap_send() and cleared on exit.
-
- void mail_unlock (MAILSTREAM *stream)
- This function releases the stream lock. It is an error to release
- the stream lock if the stream is not locked.
-